package com.halfsword.creativecraft.loot;

import com.google.common.base.Suppliers;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.loot.LootModifier;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.NotNull;

import java.util.function.Supplier;

/**
 * 自定义全局战利品修改器 - 用于可疑沙子(sus sand)的特殊掉落逻辑
 *
 * <h3>核心功能：</h3>
 * 1. 有17%的概率清空原有战利品并添加指定物品
 * 2. 总是添加一个指定物品到战利品列表
 *
 * <p>设计用于在可疑沙子(suspicious sand)中生成特定物品，同时保留原版掉落机制</p>
 * <p>由 DEEPSEEK 提供注释</p>
 */
public class AddSusSandItemModifier extends LootModifier {

    /**
     * CODEC 实例 - 用于序列化和反序列化
     *
     * <p>使用 Suppliers.memoize 延迟初始化以提高性能：</p>
     * <ul>
     *   <li>codecStart() - 处理基础战利品条件</li>
     *   <li>ForgeRegistries.ITEMS.getCodec() - 从注册表获取物品</li>
     *   <li>fieldOf("item") - 定义配置中的 "item" 字段</li>
     * </ul>
     */
    public static final Supplier<Codec<AddSusSandItemModifier>> CODEC = Suppliers.memoize(() ->
            RecordCodecBuilder.create(inst -> codecStart(inst)
                    .and(ForgeRegistries.ITEMS.getCodec()
                            .fieldOf("item")
                            .forGetter(m -> m.item))
                    .apply(inst, AddSusSandItemModifier::new)
            ));

    /** 要添加到战利品中的物品 */
    private final Item item;

    /**
     * 构造函数
     *
     * @param conditionsIn 战利品条件数组（决定何时应用此修改器）
     * @param item         要添加到战利品中的物品
     */
    public AddSusSandItemModifier(LootItemCondition[] conditionsIn, Item item) {
        super(conditionsIn);
        this.item = item;
    }

    /**
     * 应用战利品修改逻辑
     *
     * <h3>执行流程：</h3>
     * <ol>
     *   <li>检查所有战利品条件是否满足（AND关系）</li>
     *   <li>如果条件不满足，返回原始战利品</li>
     *   <li>有17%概率：清空战利品并添加一个指定物品</li>
     *   <li>总是：添加一个指定物品到战利品列表</li>
     * </ol>
     *
     * @param generatedLoot 当前生成的战利品列表
     * @param context       战利品生成上下文（包含随机数生成器等）
     * @return 修改后的战利品列表
     */
    @NotNull
    @Override
    protected ObjectArrayList<ItemStack> doApply(ObjectArrayList<ItemStack> generatedLoot, LootContext context) {
        // 检查所有条件是否满足（AND关系）
        if (!this.test(context)) {
            return generatedLoot;
        }

        // 17%概率清空战利品并添加一个指定物品
        if (context.getRandom().nextFloat() < 0.17f) {
            generatedLoot.clear();
            generatedLoot.add(new ItemStack(this.item));
        }

        // 总是添加一个指定物品到战利品列表
        generatedLoot.add(new ItemStack(this.item));
        return generatedLoot;
    }

    /**
     * 获取此修改器的编解码器
     *
     * @return 注册的编解码器实例
     */
    @Override
    public Codec<? extends IGlobalLootModifier> codec() {
        return CODEC.get();
    }

    /**
     * 检查所有战利品条件是否满足
     *
     * <p>使用AND逻辑：所有条件必须同时满足</p>
     *
     * @param context 战利品生成上下文
     * @return 所有条件是否满足
     */
    private boolean test(LootContext context) {
        for (LootItemCondition condition : this.conditions) {
            if (!condition.test(context)) {
                return false;
            }
        }
        return true;
    }
}